package com.onlyxiahui.framework.action.dispatcher.extend.impl;

import java.util.Set;

import org.springframework.core.MethodParameter;

import com.onlyxiahui.framework.action.dispatcher.ActionContext;
import com.onlyxiahui.framework.action.dispatcher.extend.ActionRequest;
import com.onlyxiahui.framework.action.dispatcher.extend.ActionResponse;
import com.onlyxiahui.framework.action.dispatcher.extend.ArgumentBox;
import com.onlyxiahui.framework.action.dispatcher.extend.MethodArgumentResolver;

/**
 * Date 2019-01-12 15:42:48<br>
 * Description
 * 
 * @author XiaHui<br>
 * @since 1.0.0
 */

public class DefaultMethodArgumentResolver implements MethodArgumentResolver {

	@Override
	public boolean supportsParameter(MethodParameter parameter) {
		return true;
	}

	@Override
	public Object resolveArgument(ActionContext actionContext, MethodParameter parameter, ActionRequest request, ActionResponse response, ArgumentBox argumentBox) {
		// Type type = parameter.getGenericParameterType();
		Class<?> clazz = parameter.getParameterType();
		Object data = null;
		if (null != clazz) {
			if (clazz.isAssignableFrom(ActionContext.class)) {
				data = actionContext;
			} else if (clazz.isAssignableFrom(ActionRequest.class)) {
				data = request;
			} else if (clazz.isAssignableFrom(ActionResponse.class)) {
				data = response;
			} else if (clazz.isAssignableFrom(ArgumentBox.class)) {
				data = argumentBox;
			} else {
				data = argumentBox.get(clazz);
				if (null == data) {
					Set<Object> keys = argumentBox.keySet();
					if (null != keys) {
						for (Object o : keys) {
							if (o instanceof Class) {
								Class<?> classKey = (Class<?>) o;
								if (clazz.isAssignableFrom(classKey)) {
									data = argumentBox.get(o);
									break;
								}
							}
						}
					}
				}
				if (null == data) {
					data = getValue(actionContext, clazz);
				}
			}
		}
		return data;
	}

	private Object getValue(ActionContext actionContext, Class<?> clazz) {
		return actionContext.getArgumentDefaultValueBuilderRegistry().getValue(clazz);
	}
}
